import numpy as np
import matplotlib.pyplot as plt

def model(theta,x):
    return x.dot(theta)

def cost(h,y):
    return 0.5 * np.mean((h-y) ** 2)

def grad(x,y,iter0=500000,alpha=0.001):
    m,n = x.shape
    theta = np.ones(n)
    J=np.zeros(iter0)
    for i in range(iter0):
        h = model(theta,x)
        J[i]=cost(h,y)
        dt=1/m*x.T.dot(h-y)
        theta-=alpha*dt
    return h,theta,J
#精度
def score(h,y):
    u=np.sum((h-y)**2)
    miu=np.mean(y)
    v=np.sum((y-miu)**2)
    return 1-u/v

if __name__ == '__main__':
    data=np.loadtxt('ex1data2.txt',delimiter=',')

    x=data[:,:-1]
    y=data[:,-1]
    #m：样本个数
    m=len(x)
#缩放
    max_x=np.max(x,axis=0)
    min_x=np.min(x,axis=0)
    x=(x-min_x)/(max_x-min_x)
    #拼接
    X=np.c_[np.ones(m),x]
    #洗牌
    np.random.seed(666)
    a=np.random.permutation(m)
    X=X[a]
    y=y[a]
    #切分训练集 测试集
    num=int(0.7*m)
    train_x,test_x=np.split(X,[num,])
    train_y,test_y=np.split(y,[num,])

    #训练模型
    train_h,theta,J=grad(train_x,train_y)

    plt.plot(J)
    plt.show()

    print('训练集精度',score(train_h,train_y))
    test_h=model(theta,test_x)
    print('测试集精度',score(test_h,test_y))